import SceneBase from "../../engine/scene/SceneBase";
import PressNodeManager from "../manager/PressNodeManager";
import { Logger } from "../../engine/utils/Logger";
import MusicInfo from "../config/MusicInfo";
import GameConfig from "../config/GameConfig";
import MusicItem, { MusicItem_Type, MusicItem_Side } from "../config/MusicItem";
import { MoveHelper } from "../../engine/utils/MoveHelper";
import ArrowManager from "../manager/ArrowManager";
import LineManager from "../manager/LineManager";
import MathUtils from "../../engine/utils/MathUtils";

const { ccclass, property } = cc._decorator;

@ccclass
export default class RhythmScene extends SceneBase {

    public static scriptName: string = "RhythmScene";

    @property({ type: [cc.Node] })
    private btnPressList: Array<cc.Node> = [];

    @property({ type: cc.Prefab })
    private pressPrefab: cc.Prefab = null;

    @property({ type: cc.Prefab })
    private arrowPrefab: cc.Prefab = null;

    @property({ type: cc.Prefab })
    private linePrefab: cc.Prefab = null;

    @property({ type: cc.Node })
    private itemContainer: cc.Node = null;

    @property({ type: cc.Node })
    private arrowContainer: cc.Node = null;

    @property({ type: cc.Node })
    private lineContainer: cc.Node = null;


    private isPressDown: boolean = false;
    private frameCount: number = 0;

    private musicInfo: MusicInfo;
    private musicItemCount: number = 0;

    private initScale: number = 0.2;

    private initPList: Array<cc.Vec2> = [
        cc.v2(-56.244, 273.374),
        cc.v2(-2.242, 273.374),
        cc.v2(57.758, 273.374),
        cc.v2(107.758, 273.374),
    ];

    private gotoPList: Array<cc.Vec2> = [
        cc.v2(-389.002, -152.899),
        cc.v2(-106.017, -152.899),
        cc.v2(162.983, -152.899),
        cc.v2(422.983, -152.899),
        // cc.v2(-511.657, -403.42),
        // cc.v2(-131.657, -403.42),
        // cc.v2(202.343, -403.42),
        // cc.v2(472.343, -403.42),
    ];

    private itemList: Array<MusicItem> = [];

    private speed: number = 0;

    private moveRadList: Array<number> = [

    ];


    onLoadMe() {
        PressNodeManager.instance.init(this.pressPrefab);
        ArrowManager.instance.init(this.arrowPrefab);
        LineManager.instance.init(this.linePrefab)
        for (let i = 0; i < this.btnPressList.length; i++) {
            this.btnPressList[i].on(cc.Node.EventType.MOUSE_DOWN, this.onPressDown.bind(this))
            this.btnPressList[i].on(cc.Node.EventType.MOUSE_MOVE, this.onPressMove.bind(this))
            this.btnPressList[i].on(cc.Node.EventType.MOUSE_UP, this.onPressUp.bind(this))

            this.moveRadList[i] = Math.atan2(this.gotoPList[i].y - this.initPList[i].y, this.gotoPList[i].x - this.initPList[i].x)

            Logger.log("rot===", MathUtils.radiansToDegrees(this.moveRadList[i]))
        }
        this.musicInfo = GameConfig.getMusicInfo(1)
        this.musicItemCount = 0;
        this.checkProductItem();
    }

    private onPressDown(event: cc.Event) {
        Logger.log("onPressDown==", event)
        this.isPressDown = true;
    }

    private onPressMove(event: cc.Event) {
        if (this.isPressDown) {
            Logger.log("onPressMove==", event)
        }
    }

    private onPressUp(event: cc.Event) {
        Logger.log("onPressUp==", event)
        this.isPressDown = false;
    }

    private checkProductItem() {
        let musicItems: Array<MusicItem> = this.musicInfo.itemList;
        for (let i = this.musicItemCount; i < musicItems.length; i++) {
            let musicItem: MusicItem = musicItems[i];
            if (this.frameCount >= musicItem.appeartTime) {
                this.initMusiItem(musicItem, null);
                this.moveMusicItem(this.musicInfo.speedTime, musicItem, true)
                let moveDistance: number = MathUtils.distance(musicItem.initP, musicItem.targetP);
                this.speed = moveDistance / this.musicInfo.speedTime;
                this.checkInitChildMusicItem(musicItem)
                this.musicItemCount++;
            }
        }
    }

    private checkInitChildMusicItem(musicItem: MusicItem) {
        if (musicItem.childItem) {
            this.initMusiItem(musicItem.childItem, musicItem)
            let moveDistance: number = MathUtils.distance(musicItem.childItem.initP, musicItem.childItem.targetP);
            let speedTime: number = moveDistance / this.speed;
            this.moveMusicItem(this.musicInfo.speedTime, musicItem.childItem, false)
            // this.moveMusicItem(speedTime, musicItem.childItem)
            this.checkInitChildMusicItem(musicItem.childItem) //递归遍所有的子孩子
        }
    }

    private initMusiItem(musicItem: MusicItem, parentItem: MusicItem) {
        let item: cc.Node = null;
        musicItem.parentItem = parentItem;
        if (parentItem) {
            musicItem.initP = parentItem.initP.clone();
            musicItem.targetP = parentItem.targetP.clone();
        } else {
            musicItem.initP = this.initPList[musicItem.col].clone();
            musicItem.targetP = this.gotoPList[musicItem.col].clone();
        }
        let realDistance: number = musicItem.distance * this.initScale;
        if (musicItem.type == MusicItem_Type.PressNode) {
            item = PressNodeManager.instance.createPressNode();
            this.itemContainer.addChild(item)
        } else if (musicItem.type == MusicItem_Type.Arrow) {
            item = ArrowManager.instance.getNode();
            item.angle = MusicItem.getRotationBySideAndCol(musicItem.side, musicItem.col)
            let degress: number = MathUtils.degreesToRadians(180 - item.angle);
            musicItem.initP.x += realDistance * Math.cos(degress)
            musicItem.initP.y -= realDistance * Math.sin(degress);
            musicItem.targetP.x += musicItem.distance * Math.cos(degress);
            musicItem.targetP.y -= musicItem.distance * Math.sin(degress);
            this.arrowContainer.addChild(item)
        } else if (musicItem.type == MusicItem_Type.Line) {
            item = LineManager.instance.getNode();
            item.angle = MusicItem.getRotationBySideAndCol(musicItem.side, musicItem.col)
            item.width = musicItem.distance;
            this.lineContainer.addChild(item)
            let degress: number = MathUtils.degreesToRadians(180 - item.angle);
            musicItem.initP.x += realDistance * Math.cos(degress)
            musicItem.initP.y -= realDistance * Math.sin(degress);
            musicItem.targetP.x += musicItem.distance * Math.cos(degress);
            musicItem.targetP.y -= musicItem.distance * Math.sin(degress);
        }
        item.setScale(this.initScale)
        musicItem.node = item;
        item.setPosition(musicItem.initP)
        this.itemList.push(musicItem)
    }

    private reInitMusicItem(musicItem: MusicItem, isHead:boolean) {
        if (musicItem && musicItem.childItem) {
            Logger.log("reInitMusicItem==", musicItem.childItem)
            musicItem.childItem.targetP = musicItem.targetP.clone();
            if(musicItem.parentItem){
                let degress: number = MathUtils.degreesToRadians(180 - musicItem.childItem.node.angle);
                if (musicItem.childItem.type == MusicItem_Type.Arrow) {
                    musicItem.childItem.targetP.x += musicItem.childItem.distance * Math.cos(degress);
                    musicItem.childItem.targetP.y -= musicItem.childItem.distance * Math.sin(degress);
                } else if (musicItem.childItem.type == MusicItem_Type.Line) {
                    musicItem.childItem.targetP.x += musicItem.childItem.distance* Math.cos(degress);
                    musicItem.childItem.targetP.y -= musicItem.childItem.distance * Math.sin(degress);
                }
            }
            Logger.log("reInitMusicItem=22=",musicItem.childItem.distance, musicItem,musicItem.childItem, musicItem.targetP, musicItem.childItem.targetP)
            let moveDistance: number = MathUtils.distance(musicItem.childItem.node.getPosition(), musicItem.childItem.targetP);
            let speedTime: number = moveDistance / this.speed;
            this.moveMusicItem(speedTime, musicItem.childItem, isHead)
            // this.moveMusicItem(this.musicInfo.speedTime, musicItem.childItem)
            this.reInitMusicItem(musicItem.childItem, false)
        }
    }

    private moveMusicItem(speedTime: number, musicItem: MusicItem, isHead:boolean) {
        let seq = cc.sequence(cc.spawn(cc.moveTo(speedTime, musicItem.targetP), cc.scaleTo(speedTime, 1, 1)), cc.callFunc(() => {
            if (isHead && !musicItem.parentItem) {
                this.reInitMusicItem(musicItem, isHead)
                Logger.log("recover item=", musicItem)
                if (musicItem.type == MusicItem_Type.PressNode) {
                    PressNodeManager.instance.recoverNode(musicItem.node)
                } else if (musicItem.type == MusicItem_Type.Arrow) {
                    ArrowManager.instance.recoverNode(musicItem.node)
                } else if (musicItem.type == MusicItem_Type.Line) {
                    LineManager.instance.recoverNode(musicItem.node)
                }
                if(musicItem.childItem){
                    musicItem.childItem.parentItem = null;
                }
            }
        }));
        musicItem.node.runAction(seq);
    }

    private checkMoveMusiItem() {

    }

    update(dt) {
        this.frameCount++;
        this.checkProductItem();
    }

    onDestroyMe() {

    }
}